//
// SoapTrace.Net - A soap message monitoring utility. 
//
// Copyright (C) 2005 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using SoapTrace.Core.Diagnostics;
using System;
using System.IO;
using System.Runtime.Remoting;

namespace SoapTrace.Core.Formatters
{
	/// <summary>
	/// Manages objects that implement that IMessageFormatter interface.
	/// </summary>
	public class MessageFormatterManager
	{
		/// <summary>
		/// Custom message formatters configured.
		/// </summary>
		private MessageFormattersCollection m_MessageFormatters =
			new MessageFormattersCollection( );
		
		/// <summary>
		/// The basic built-in soap message formatter.
		/// </summary>
		private SimpleMessageFormatter m_SimpleMessageFormatter = 
			new SimpleMessageFormatter( );
		
		/// <summary>
		/// The currently selected custom formatter if any.
		/// </summary>
		private IMessageFormatter m_SelectedCustomFormatter = null;
		
		/// <summary>
		/// Creates a new instance of the 
		/// <see cref="MessageFormatterManager"/> class.
		/// </summary>
		public MessageFormatterManager( MessageFormatterEntryCollection entries )
		{
			CreateMessageFormatters( entries );
			
			m_SimpleMessageFormatter.FormatSoapMessage = true;
		}
		
		/// <summary>
		/// Gets the custom formatters.
		/// </summary>
		public MessageFormattersCollection CustomFormatters
		{
			get
			{
				return m_MessageFormatters;
			}
		}
		
		/// <summary>
		/// Indicates whether a custom formatter is being used.
		/// </summary>
		public bool IsCustomFormatterSelected
		{
			get
			{
				bool IsSelected = false;
				
				if( m_SelectedCustomFormatter != null )
				{
					IsSelected = true;
				}
				
				return IsSelected;
			}
		}
		
		/// <summary>
		/// Gets the custom message formatter names.
		/// </summary>
		public string[ ] GetCustomFormatterNames( )
		{
			string[ ] Names = new string[ m_MessageFormatters.Count ];

			for( int i = 0; i < m_MessageFormatters.Count; ++i )
			{
				IMessageFormatter Formatter = m_MessageFormatters[ i ];
				Names[ i ] = Formatter.Name;
			}
			
			return Names;
		}
		
		/// <summary>
		/// Gets the currently active message formatter.
		/// </summary>
		public IMessageFormatter CurrentFormatter
		{
			get
			{
				IMessageFormatter Formatter = m_SelectedCustomFormatter;
				
				if( Formatter == null )
				{
					Formatter = m_SimpleMessageFormatter;
				}
				
				return Formatter;
			}
		}
		
		/// <summary>
		/// Makes the specified custom formatter the current formatter.
		/// </summary>
		/// <param name="name">The name of the custom
		/// formatter.</param>
		public void SelectCustomFormatter( string name )
		{
			m_SelectedCustomFormatter = m_MessageFormatters[ name ];
		}
		
		/// <summary>
		/// Deselects all the custom formatters.
		/// </summary>
		public void DeselectAllCustomFormatters( )
		{
			m_SelectedCustomFormatter = null;
		}
		
		/// <summary>
		/// Gets or sets whether soap headers will be shown with
		/// the simple message formatter.
		/// </summary>
		public bool ShowSoapHeaders
		{
			get
			{
				return m_SimpleMessageFormatter.ShowSoapHeaders;
			}
			
			set
			{
				m_SimpleMessageFormatter.ShowSoapHeaders = value;
			}
		}
		
		/// <summary>
		/// Gets or sets whether the soap envelope will be shown with
		/// the simple message formatter.
		/// </summary>
		public bool ShowSoapEnvelope
		{
			get
			{
				return m_SimpleMessageFormatter.ShowSoapEnvelope;
			}
			
			set
			{
				m_SimpleMessageFormatter.ShowSoapEnvelope = value;
			}
		}
		
		/// <summary>
		/// Gets or sets whether the soap message parameters will be shown 
		/// with the simple message formatter.
		/// </summary>
		public bool ShowSoapMessageParameters
		{
			get
			{
				return m_SimpleMessageFormatter.ShowSoapMessageParameters;
			}
			
			set
			{
				m_SimpleMessageFormatter.ShowSoapMessageParameters = value;
			}
		}	
		
		/// <summary>
		/// Gets or sets whether the raw soap message will be shown 
		/// with the simple message formatter.
		/// </summary>
		public bool ShowRawSoapMessage
		{
			get
			{
				return !m_SimpleMessageFormatter.FormatSoapMessage;
			}
			
			set
			{
				m_SimpleMessageFormatter.FormatSoapMessage = !value;
			}
		}		
		
		/// <summary>
		/// Creates message formatter objects for the currently configured
		/// entries in the config file.  
		/// </summary>
		/// <param name="entries">A collection of message formatter
		/// entries.</param>
		/// <remarks>We currently support multiple message
		/// formatter objects.  For each one specified in the
		/// config file we create an instance of the formatter object.  The
		/// stored formatter objects will be used to format the soap
		/// messages based on the currently selected formatter.</remarks>
		private void CreateMessageFormatters( MessageFormatterEntryCollection entries )
		{
			Logger.Log( "Creating message formatters..." );
			
			foreach( MessageFormatterEntry Entry in entries )
			{
				try
				{
					ObjectHandle FormatterObject = Activator.CreateInstance( Entry.AssemblyName, Entry.TypeName );
					
					IMessageFormatter Formatter = FormatterObject.Unwrap( ) as IMessageFormatter;
	
					if( Formatter != null )
					{
						Logger.Log( String.Concat( "Adding formatter '", Entry.FullTypeName, "'." ) );
				
						m_MessageFormatters.Add( Formatter );
					}
					else
					{
						Logger.LogError( 
							String.Concat( "Formatter '", Entry.FullTypeName, 
							"' does not implement the IMessageFormatter interface." ) );
					}
				}
				catch( FileNotFoundException Ex )
				{
					Logger.LogError( String.Concat( "Could not create '", Entry.FullTypeName, "'.  ", Ex.ToString( ) ) );
				}
			}
			
			Logger.Log( "Created formatters." );
		}
	}
}
